﻿// Shader-Based-Image-Processing (SBIP)
// http://code.google.com/p/sbip/
//
// Copyright © Frank Nagl, 2009-2010
// admin@franknagl.de
//
namespace SBIP.Filter
{
    using Microsoft.Xna.Framework.Graphics;

    /// <summary>
    /// Sobel edge detector.
    /// </summary>
    /// <remarks><para>The filter searches for objects' edges by applying Sobel operator.</para>
    /// 
    /// <para>Each pixel of the result image is calculated as approximated absolute gradient
    /// magnitude for corresponding pixel of the source image:
    /// <code lang="none">
    /// |G| = |Gx| + |Gy] ,
    /// </code>
    /// where Gx and Gy are calculate utilizing Sobel convolution kernels:
    /// <code lang="none">
    ///    Gx         Gy
    /// -1 0 +1    +1 +2 +1
    /// -2 0 +2     0  0  0
    /// -1 0 +1    -1 -2 -1
    /// </code>
    /// Using the above kernel the approximated magnitude for pixel <b>x</b> is calculate using
    /// the next equation:
    /// <code lang="none">
    /// P1 P2 P3
    /// P8  x P4
    /// P7 P6 P5
    /// 
    /// |G| = |P1 + 2P2 + P3 - P7 - 2P6 - P5| +
    ///       |P3 + 2P4 + P5 - P1 - 2P8 - P7|
    /// </code>
    /// </para>
    ///	
    /// <para>Sample usage:</para>
    /// <code>
    ///  // 1. Offline rendering
    ///  // create Processor, used as rendering framework
    ///  Processor processor = new Processor();
    ///  // starts Processor
    ///  processor.Begin( image );
    ///  // create SobelEdgeDetector filter
    ///  SobelEdgeDetector filter = new SobelEdgeDetector( true );
    ///  processor.Filter = filter;
    ///  // apply the filter  
    ///  Bitmap resultImage = processor.RenderToBitmap( );
    ///  Texture2D resultTexture = processor.RenderToTexture( );
    ///  processor.End( );
    ///  
    ///  // 2. Online rendering
    ///  // create any windows control for rendering in
    ///  Form myForm = new Form( );
    ///  // create Processor, used as rendering framework
    ///  Processor processor2 = new Processor( );
    ///  // starts Processor
    ///  processor2.Begin( image, myForm );
    ///  // create SobelEdgeDetector filter
    ///  SobelEdgeDetector filter2 = new SobelEdgeDetector( false );
    ///  processor2.Filter = filter2;  
    ///  // apply the filter
    ///  myForm.Show( );
    ///  while ( myForm.Created )
    ///  {
    ///      processor2.Render( );
    ///      Application.DoEvents( );
    ///  }
    ///  processor2.End( );
    /// </code>
    /// 
    /// <para><b>Initial image:</b></para>
    /// <img src="img/shaderbased/sample1.jpg" width="480" height="361" />
    /// <para><b>Result image:</b></para>
    /// <img src="img/shaderbased/SobelEdgeDetector.jpg" width="480" height="361" />
    /// </remarks>
    public sealed class SobelEdgeDetector : BaseFilter
    {
        private bool isColored;
        /// <summary>
        /// Indicating whether edge image is colored of grayscaled. 
        /// Default: false.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if edge image will be colored, 
        /// 	otherwise edge image is grayscaled.
        /// </value>
        public bool IsColored
        {
            get { return isColored; }
            set
            {
                if (Effect == null)
                    throw new System.ArgumentException("IsColored" + InitMsg);

                isColored = value;
                Effect.Parameters["IsColored"].SetValue(value);

            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SobelEdgeDetector"/> 
        /// class.
        /// </summary>        
        public SobelEdgeDetector() : base("SobelEdgeDetector") { }

        /// <summary>
        /// Defines, that Sobel edge detector is not colored.
        /// </summary>
        protected override void PostInit()
        {
            IsColored = false;
        }
    }
}
